package cdu.sl.aop;

import cdu.sl.mapper.OperateLogMapper;
import cdu.sl.pojo.OperateLog;
import cdu.sl.utils.CurrentHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

@Aspect
@Component
public class OperateLogAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger(OperateLogAspect.class);

    @Autowired
    private OperateLogMapper operateLogMapper;

    @Pointcut("@annotation(cdu.sl.anno.OperateLog)")
    public void controllerMethods() {
    }

    @Around("controllerMethods()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();

        // 获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String className = signature.getDeclaringTypeName();
        String methodName = signature.getName();

        // 获取方法参数
        String methodParams = Arrays.toString(joinPoint.getArgs());

        // 获取操作人ID（这里假设通过某种方式获取，例如从SecurityContext中获取）
        Integer operateEmpId = getOperateEmpId();

        // 执行目标方法
        Object result = joinPoint.proceed();

        // 计算方法执行耗时
        long endTime = System.currentTimeMillis();
        long costTime = endTime - startTime;

        // 获取返回值
        String returnValue = result == null ? "" : result.toString();

        // 创建OperateLog对象
        OperateLog operateLog = new OperateLog();
        operateLog.setOperateEmpId(operateEmpId);
        operateLog.setOperateTime(LocalDateTime.now());
        operateLog.setClassName(className);
        operateLog.setMethodName(methodName);
        operateLog.setMethodParams(methodParams);
        operateLog.setReturnValue(returnValue);
        operateLog.setCostTime(costTime);

        // 保存日志
        LOGGER.info("操作日志：{}", operateLog);
        operateLogMapper.insert(operateLog);

        return result;
    }

    /**
     * 获取当前进行操作的员工ID
     * @return
     */
    private Integer getOperateEmpId() {
        return CurrentHolder.getCurrentId(); // 从ThreadLocal中获取到当前登录的员工ID
    }
}
